<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2019/11/1
 * Time: 15:42
 */

namespace app\adminapiv3\service\platform_manage;

use app\adminapiv3\service\BaseService;
use app\adminapiv3\service\Password;
use app\adminapiv3\service\Upload;
use app\common\model\FilePathModel;
use app\common\model\RivestCipher;
use app\common\service;
use think\Db;
use think\Exception;


class ServerAuthService extends BaseService
{
    /**
     * @name 授权列表
     * @param $params
     * @return array
     * @author wx
     * @date 2019/11/7 13:57
     */
    public function list($params, $groupId)
    {
        $server = new \app\common\service\platform_manage\ServerAuthService();
        $list = $server->list($params, $groupId);
        //处理数据
        foreach($list['data'] as $k => $v){
            $v['stime'] = date('Y-m-d H:i:s', $v['stime']);
            $v['etime'] = $v['etime'] == 0 ? '永久授权' : date('Y-m-d H:i:s', $v['etime']);
            $list['data'][$k] = $v;
        }

        return $list;
    }

    /**
     * @name 离线授权
     * @author wx
     * @date 2019/12/2 15:28
     */
    public function offline($file)
    {
        //记录操作日志
        global $logArray;
        $logArray = array(
            'content' => '离线授权注册',
        );

        //1. 上传文件
        $uploadServer = new Upload();
        $uploadAuthDir = '../runtime/Upload/Auth';
        $uploadRes = $uploadServer->upload($file, $uploadAuthDir,'key',5*1024*1024);

        if($uploadRes['code'] != 0){
            $this->setError($this->CODE_FAIL, $uploadRes['msg']);
            return false;
        }

        //2. 解密文件
        $authFile = $uploadRes['path'].$uploadRes['file_name'];
        $rc4Server = new RivestCipher();

        $content = file_get_contents($authFile);

        $authInfo = $rc4Server->decrypt($content);

        if(!$authInfo){
            $this->setError($this->CODE_FAIL, '错误的授权文件');
            return false;
        }

        foreach ($authInfo as $k => $v){

            $this->checkData($v);
            
            $this->checkLocal($v);

            //检测授权时间
            $this->checkAuthTime($v, $this->getSystemTime());

            //验证授权数量和时间
            $this->checkNumberAndTime($v);
        }

        //4. 处理数据
        return $this->handleData($authInfo);
    }

    /**
     * @name: 平台授权信息
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-20 17:44:33
     */
    public function platformAuthInfo ()
    {
        //这里返回的是授权的版本,真正的版本号在更新日志那里查看,这里不显示真正的版本是因为云南那边要求显示1.5
        $field = 'product_name,company_name,version_key, product_m_version';
        $authInfo = Db::name('server_auth')->field($field)->find();

        return $authInfo;
    }

    /**
     * @name 获取平台基本硬件信息 UUID 网卡,网关等
     * @author wx
     * @date 2019/11/28 16:06
     */
    public function getPlatformBaseInfo()
    {
        $model = new FilePathModel();
        $platformBaseFile = $model->platform_base_info;

        if(!file_exists($platformBaseFile)){//强制停止
            returnErrJson($this->CODE_FAIL, '无系统主机码文件,请联系维护人员');
        }

        $content = file_get_contents($platformBaseFile);
        $platformBaseInfo = json_decode($content, true);

        return $platformBaseInfo;
    }

    /**
     * @name 检查是否是本机授权
     * @param $info
     * @return bool
     * @author wx
     * @date 2019/11/29 15:37
     */
    public function checkLocal($info)
    {
        $platformBaseInfo = $this->toDo('getPlatformBaseInfo');//平台UUID

        if ($info['uuid'] != $platformBaseInfo['hostkey']) {
            returnErrJson($this->CODE_FAIL, '不是本机授权');
        }

        return true;
    }

    /**
     * @name 验证授权时间
     * @param $info
     * @return bool
     * @author wx
     * @date 2019/11/29 15:39
     */
    public function checkAuthTime($info, $nowTime)
    {
        if ($info['etime'] != 0 && $info['etime'] <= $nowTime) {
            returnErrJson($this->CODE_FAIL, '授权已到期');
        }

        return true;
    }


    /**
     * @name 验证数据是否符合标准
     * @param $info
     * @author wx
     * @date 2019/11/29 15:41
     */
    public function checkData($info)
    {

        $array = array(
            'unit_name',
            'auth_key',
            'company_name',
            'product_id',
            'product_name',
            'module_name',
            'product_key',
            'product_m_version',
            'product_c_version',
            'number',
            'stime',
            'etime',
            'type',
            'mode',
            'is_port',
            'address_json',
            'uuid',
            'maintain_password',
            'version_name',
            'version_key',
        );

        foreach ($array as $v){

            if (!isset($info[$v])) {
                returnErrJson($this->CODE_FAIL, '错误的授权文件');
            }
        }


        return true;
    }

    /**
     * @name 检测模块授权时间和数量
     * @author wx
     * @date 2020/12/25 13:38
     */
    public function checkNumberAndTime($info)
    {
        //查询当前模块授权数据
        $moduleInfo = Db::name('server_auth_module')->where('module_key', $info['product_key'])->find();
        if($moduleInfo){
            if ($moduleInfo['number'] > $info['number']) {
                returnErrJson($this->CODE_FAIL, $moduleInfo['module_name'].'模块授权数量不能少于'.$moduleInfo['number']);
            }

            if ($info['etime'] != 0 && $moduleInfo['etime'] > $info['etime']) {
                returnErrJson($this->CODE_FAIL, $moduleInfo['module_name'].'模块授权时间不能少于'.date('Y-m-d', $moduleInfo['etime']));
            }
        }

        return true;
    }

    /**
     * @name 生成主机码文件
     * @return bool
     * @author wx
     * @date 2019/12/2 13:32
     */
    public function createHostFile()
    {
        $dir = './static/host/';
        $fileName = 'hostkey.key';

        if (!file_exists($dir.$fileName)) {

            if (!file_exists($dir)) {
                mkdir($dir, 0777, true);
            }

            $serverInfo = $this->getPlatformBaseInfo();

            $requestData = array(
                'ip' => $_SERVER['SERVER_ADDR'],
                'system' => $serverInfo['os'],
                'alias' => $serverInfo['alias'],
                'uuid' => $serverInfo['hostkey'],
            );

            $rc4Server = new RivestCipher();
            $rc4Data = $rc4Server->encrypt($requestData);

            file_put_contents($dir.$fileName, $rc4Data);
        }

        return true;
    }

    /**
     * @name 授权数据处理
     * @param $authArr
     * @author wx
     * @date 2019/12/2 14:56
     */
    public function handleData($authArr)
    {
        $dbConf = config('database.');
        $tableModuleName = $dbConf['prefix'].'host_module_relation';

        $hostModuleServer = new \app\common\model\HostModuleRelation();

        //开启事务
        Db::startTrans();
        try{

            foreach ($authArr as $k => $v){
                //主表数据
                $Data = array(
                    'unit_name' => $v['unit_name'],
                    'auth_key' => $v['auth_key'],
                    'company_name' => $v['company_name'],
                    'product_id' => $v['product_id'],
                    'product_name' => $v['product_name'],
                    'product_m_version' => $v['product_m_version'],
                    'mode' => $v['mode'],
                    'address_json' => $v['address_json'],
                    'version_name' => $v['version_name'],
                    'version_key' => $v['version_key'],
                );

                //查询主表是否有数据,无则插入,有则更新
                $authInfo = Db::name('server_auth')->find();
                if(!$authInfo){
                    //添加
                    Db::name('server_auth')->insert($Data);
                }else{
                    //修改
                    Db::name('server_auth')->where('id', $authInfo['id'])->update($Data);
                }

                //模块表数据
                $moduleData = [
                    'module_name' => $v['module_name'],
                    'module_key' => $v['product_key'],
                    'number' => $v['number'],
                    'stime' => $v['stime'],
                    'etime' => $v['etime'],
                    'product_c_version' => $v['product_c_version'],
                    'is_port' => $v['is_port'],
                ];

                //模块数据 根据模块key 存在则修改,不存在则插入
                if(!Db::name('server_auth_module')->where('module_key', $v['product_key'])->find()){
                    //添加
                    Db::name('server_auth_module')->insert($moduleData);
                }else{
                    //修改
                    Db::name('server_auth_module')->where('module_key', $v['product_key'])->update($moduleData);
                }


                //2. 创建模块
                $moduleName = $v['product_key'];
                $moduleComment = $v['product_name'];

                $fieldNum = $hostModuleServer->checkField($moduleName);

                if($fieldNum == 0){//创建模块
                    $createModule = "ALTER TABLE `$tableModuleName` ADD COLUMN `$moduleName`  tinyint(1) NOT NULL DEFAULT 0 COMMENT '$moduleComment';";
                    Db::query($createModule);
                }

                if($v['type'] == 1){

                    //3. 公司入库
                    $companyInfo = Db::name('host_ministry')->where('pid',0)->find();

                    if(empty($companyInfo)){
                        $addCompany['name'] = $v['unit_name'];
                        $addCompany['pid'] = 0;
                        $addCompany['ctime'] = time();

                        Db::name('host_ministry')->insert($addCompany);
                    }

                    //5. 改变版本号
//                    $versionServer = new service\ServerVersion();
//                    $versionServer->setServerVersion($v['product_m_version']);
                }

            }

            Db::commit();
            return true;
        }catch (Exception $e){
            Db::rollback();

            $this->setError($this->CODE_FAIL,'操作失败');
            return false;
        }


    }

    /**
     * @name 在线授权
     * @author wx
     * @date 2019/12/2 15:24
     */
    public function online($key)
    {
        //记录操作日志
        global $logArray;
        $logArray = array(
            'content' => '在线授权注册',
        );

        $serverInfo = $this->getPlatformBaseInfo();
        $this->setError($this->CODE_FAIL,'此功能暂未开通');
        return false;

        //TODO 拆分表入库

        $requestData = array(
            'buyer_name' => $usm,
            'serial_number' => $key,
            'ip' => $_SERVER['SERVER_ADDR'],
            'system' => $serverInfo['os'],
            'alias' => $serverInfo['alias'],
            'uuid' => $serverInfo['hostkey'],
        );

        $url = config('request_auth_url');
        $authRes = requestCurl($url,1,$requestData);

        if($authRes['code'] != 0){
            returnErrJson($authRes['code'], $authRes['msg']);
        }

        $authData = $authRes['data'];
        foreach ($authData as $k => $v){
            $this->checkData($v);
            $this->checkLocal($v);
        }

        $this->handleData($authData);

        return true;
    }



    /**
     * @name 获取系统时间
     * @return mixed
     * @author wx
     * @date 2019/12/10 14:47
     */
    public function getSystemTime()
    {
        $model = new FilePathModel();
        $systemTimeFile = $model->system_time;
        if(!file_exists($systemTimeFile)){
            returnErrJson(101, '系统文件不存在,请联系维护工程师');
        }
        $content = file_get_contents($systemTimeFile);
        $systemTime = json_decode($content,true);
        $nowTime = $systemTime['stime'];

        return $nowTime;
    }

}